#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Author    :Timo
import asyncio
import pathlib
import threading
import time

from fastapi import FastAPI
from fastapi.requests import Request
from fastapi.responses import HTMLResponse, PlainTextResponse, JSONResponse
from fastapi.routing import APIRoute, APIRouter
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles


async def fastapi_index():
    return JSONResponse({"index": "fastapi_index"})


async def exception_not_found(request, exc):
    print(dir(exc))
    return JSONResponse({
        "code": exc.status_code,
        "error": "没有定义这个请求地址"},
        status_code=exc.status_code)


# 全局route
routes = [APIRoute(path="/fastapi/index", endpoint=fastapi_index, methods=["GET"])]
# 全局异常捕获
exception_handlers = {
    404: exception_not_found,
}

app = FastAPI(title="学习Fastapi框架文档",
              routes=routes,
              exception_handlers=exception_handlers,
              description="以下是关于相Fastapi框架文档介绍和描述",
              version="0.0.1",
              openapi_prefix='',
              swagger_ui_oauth2_redirect_url="/docs/oauth2-redirect",
              swagger_ui_init_oauth=None,
              docs_url='/docs',
              redoc_url='/redoc',
              openapi_url="/openapi/openapi_json.json",
              terms_of_service="https://terms/团队的官网网站/",
              contact={
                  "name": "邮件接收者信息",
                  "url": "https://xxx.cc",
                  "email": "583332447@qq.com",
              },
              license_info={
                  "name": "版权信息说明 License v3.0",
                  "url": "https://xxxxxxx.com",
              },
              openapi_tags=[
                  {
                      "name": "接口分组",
                      "description": "接口分组信息说明",
                  },
              ],
              # 配置服务请求地址相关的参数信息
              servers=[
                  {"url": "/", "description": "本地调试环境"},
                  {"url": "https://xx.xx.com", "description": "线上测试环境"},
                  {"url": "https://xx2.xx2.com", "description": "线上生产环境"},
              ],
              debug=True
              )

# 静态资源加载
templates = Jinja2Templates(directory=f"{pathlib.Path.cwd()}/templates/")
staticfiles = StaticFiles(directory=f"{pathlib.Path.cwd()}/static/")
app.mount("/static", staticfiles, name="static")


# 使用app实例对象来装饰实现路由注册
@app.get('/', response_class=HTMLResponse)
@app.get('/index', response_class=HTMLResponse)
@app.post('/index', response_class=HTMLResponse)
async def index(request: Request):
    return templates.TemplateResponse("index.html",
                                      {"request": request})


@app.get('/loginjig', name='loginjig')
def loginjig(request: Request):
    return PlainTextResponse('大爷')


# ============多重URL地址绑定函数============
# =========================================
@app.get('/', response_class=JSONResponse)
@app.get('/index', response_class=JSONResponse)
@app.post('/index', response_class=JSONResponse)
@app.get("/app/hello", tags=['app实例对象注册接口-示例'])
def app_hello():
    return {"Hello": "app api"}


# ============同一个URL动态和静态路由==========
# =========================================
# 动态路由
@app.get('/user/{userid}')
async def login(userid: str):
    return {"Hello": "dynamic"}


# 静态路由
@app.get('/user/userid')
async def login():
    return {"Hello": "static"}


async def index2():
    return JSONResponse({"index": "index"})


app.add_api_route(path="/index2", endpoint=index2, methods=["GET", "POST"])

router_uesr = APIRouter(prefix="/user", tags=["用户模块"])


@router_uesr.get("/user/login")
def user_login():
    return {"ok": "登入成功！"}


@router_uesr.api_route("/user/api/login", methods=['GET', 'POST'])
def user_api_route_login():
    return {"ok": "登入成功！"}


def add_user_api_route_login():
    return {"ok": "登入成功！"}


router_uesr.add_api_route("/user/add/api/login", methods=['GET', 'POST'], endpoint=add_user_api_route_login)
app.include_router(router_uesr)


@app.get(path="/async")
async def async_def():
    await asyncio.sleep(10)
    print("当前协程运行的线程ID:", threading.current_thread().ident)
    return {"index": "async"}


@app.get(path="/sync")
def sync_def():
    time.sleep(10)
    print("当前普通函数运行的线程ID:",threading.current_thread().ident)
    return {"index": "sync"}


if __name__ == '__main__':
    import uvicorn
    import os

    app_model_name = os.path.basename(__file__).replace(".py", "")
    uvicorn.run(app=f'{app_model_name}:app', host="127.0.0.1", port=65535, reload=True)
